﻿using Abp.Authorization;
using Abp.Linq.Expressions;
using Abp.UI;
using Basefr.App;
using Basefr.App.Helper;
using Basefr.Consts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Configuration;
using MySql.Data.MySqlClient;
using Paas.App.Interface.App;
using Paas.App.Interface.App.Dtos;
using Paas.App.Interface.App.Messages;
using Paas.App.Interface.Meta;
using Paas.App.Interface.Meta.Dtos;
using Paas.App.Interface.Meta.Messages;
using Paas.Core;
using Paas.Core.Const.Enums;
using Paas.Core.Meta.Entities;
using Paas.Core.MetaForms.Entities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Paas.App.Meta
{
    [Route("app-appData")]

    [AbpAuthorize()]
    public class AppDataAppService: AppService, IAppDataAppService
    {
        /// <summary>
        /// 租户数据数据库连接字符串
        /// </summary>
        private readonly string customerConStr;
        //private readonly SqlHelper _sqlHelper;
        private readonly IMainRepository<Application> _applicationRepo;
        private readonly IMainRepository<MetaObject, Guid> _metaObjectRepo;
        private readonly IMainRepository<MetaFormField, Guid> _metaFormFieldRepo;
        private readonly IMainRepository<MetaField, Guid> _metaFieldRepo;

        public AppDataAppService(IConfiguration configuration, IMainRepository<Application> applicationRepo, IMainRepository<MetaObject, Guid> metaObjectRepo, IMainRepository<MetaFormField, Guid> metaFormFieldRepo, IMainRepository<MetaField, Guid> metaFieldRepo)
        {
            customerConStr=configuration[ConnectionStringNames.Customer];
            _applicationRepo = applicationRepo; 
            _metaObjectRepo = metaObjectRepo;
            _metaFormFieldRepo = metaFormFieldRepo;
            _metaFieldRepo = metaFieldRepo;
        }

        #region 增改
        [HttpPost(nameof(SaveAppData))]
        public SaveAppDataOutput SaveAppData(SaveAppDataInput input)
        {
            if (input == null) throw new UserFriendlyException("保存信息失败：input为空！");

            //获取表单包含字段的Name值作为想筛选键的列表
            var formFieldNames = _metaFormFieldRepo.GetAllIncluding(p => p.MetaField).Where(p => p.MetaFormId==input.FormId).Select(p=>p.MetaField.Name). ToList();

            // 使用LINQ筛选字典中存在于formFieldNames中的键值对
            var filteredColumns = input.SetColumns.Where(p => formFieldNames.Contains(p.Key))
                                               .ToDictionary(p => p.Key, p => p.Value);
            if(filteredColumns.Count==0) throw new UserFriendlyException("保存信息失败：没有需要保存的数据！");
            //获取application的name作为数据库名
            var dataBaseName = (_applicationRepo.FirstOrDefault(input.ApplicationId)?.Name)??throw new UserFriendlyException("保存信息失败：未找到相关App信息！");
            //获取object的name作为表名
            var tableName = (_metaObjectRepo.FirstOrDefault(input.ObjectId)?.Name)??throw new UserFriendlyException("保存信息失败：未找到相关对象信息！");

            var conn = customerConStr+$"Initial Catalog={dataBaseName};";
            var _sqlHelper = new SqlHelper(conn);
            
            if (!filteredColumns.ContainsKey("Id")||filteredColumns["Id"]?.ToString()==Guid.Empty.ToString())//新增数据
            {
                //新增数据为Id字段赋值
                if (!filteredColumns.ContainsKey("Id"))
                {
                    filteredColumns.Add("Id", Guid.NewGuid());
                }
                else
                {
                    filteredColumns["Id"]=Guid.NewGuid();
                }
                //删除Id赋值，让主键自增
                //if (filteredColumns.ContainsKey("Id")) filteredColumns.Remove("Id");

                var result = _sqlHelper.InsertData(tableName, filteredColumns);
                if (result == 0) throw new UserFriendlyException("保存信息失败：0条新增！");
                return new SaveAppDataOutput();
            }
            else if (filteredColumns.ContainsKey("Id")&&filteredColumns["Id"]?.ToString()!=Guid.Empty.ToString())//更新数据
            {
                //根据主键Id更新数据
                var condions = new Dictionary<string, object>() { { "Id", filteredColumns["Id"] } };
                //更新时删除Id（此处可以不删，后面合并会覆盖掉）
                filteredColumns.Remove("Id");
                var result = _sqlHelper.UpdateData(tableName, filteredColumns,condions);
                if (result == 0) throw new UserFriendlyException("保存信息失败：0条更新！");
                return new SaveAppDataOutput();
            }
            
            return new SaveAppDataOutput();
        }
        #endregion

        #region 查
        [HttpPost(nameof(SearchAppData))]
        public SearchAppDataOutput SearchAppData(SearchAppDataInput input)
        {
            if (input == null) throw new UserFriendlyException("搜索信息失败：input为空！");
            //获取application的name作为数据库名
            var dataBaseName = (_applicationRepo.FirstOrDefault(input.ApplicationId)?.Name)??throw new UserFriendlyException("搜索信息失败：未找到相关App信息！");
            //获取object的name作为表名
            var tableName = (_metaObjectRepo.FirstOrDefault(input.ObjectId)?.Name)??throw new UserFriendlyException("搜索信息失败：未找到相关对象信息！");

            //获取支持模糊查询的字段
            var likeFields=_metaFormFieldRepo.GetAllIncluding(p=>p.MetaField).Where(p=>p.IsLike==true)?.Select(p=>p.MetaField.Name).ToList();
            //是否支持模糊查询
            var isLike = false;
            if (likeFields.Any())
            {
                isLike=true;
                foreach (var condition in input.Conditions)
                {
                    if (likeFields.Contains(condition.Key))
                    {
                        input.Conditions[condition.Key] = $"%{condition.Value}%";
                    }
                }
            }

            var conn = customerConStr+$"Initial Catalog={dataBaseName};";
            var _sqlHelper = new SqlHelper(conn);
            var result = _sqlHelper.QueryData(tableName, input.Conditions, isLike);

            var res = result.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            var totalCount = result.Count();
            //var resultItems = ObjectMapper.Map<AppDataDto>(res);
            
            return new SearchAppDataOutput { Items = res, TotalCount = totalCount };
            //return new SearchAppDataOutput { };
        }
        #endregion

        #region 删
        [HttpPost(nameof(DeleteAppData))]
        public  DeleteAppDataOutput DeleteAppData(DeleteAppDataInput input)
        {
            if (input == null) throw new UserFriendlyException("保存对象信息失败：input为空！");
            //获取application的name作为数据库名
            var dataBaseName = (_applicationRepo.FirstOrDefault(input.ApplicationId)?.Name)??throw new UserFriendlyException("保存对象信息失败：未找到相关App信息！");
            //获取object的name作为表名
            var tableName = (_metaObjectRepo.FirstOrDefault(input.ObjectId)?.Name)??throw new UserFriendlyException("保存对象信息失败：未找到相关对象信息！");

            var conn = customerConStr+$"Initial Catalog={dataBaseName};";
            var _sqlHelper = new SqlHelper(conn);

            Dictionary<string, object> conditions = new Dictionary<string, object>
            {
                { "Id", input.Id }
            };
            //真删除
            var result = _sqlHelper.DeleteData(tableName, conditions);
            //假删除
            //假删除实际是更新数据，使得IsDeleted=true


            return new DeleteAppDataOutput();
        }
        #endregion
    }
}
